﻿using Core.Web.Model;
using Core.DataAccess.Model.Projects;
using Core.Framework.Model.Common;
using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Core.IBusiness.ILoggerModule;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Core.Web
{
    /// <summary>
    /// 项目管理权限验证
    /// </summary>
    public class ApiProjectMemberAuthorizeAttribute : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
        }

        /// <summary>
        /// 请求参数初始值
        /// </summary>
        private void ActionArguments(ActionExecutingContext context, ProjectUser client, ApiProjectInfo project)
        {
            foreach (var item in context.ActionArguments)
            {

                // 参数未Null   跳过
                if (null == item.Value)
                    continue;

                //  获取参数类型
                Type t = item.Value.GetType();

                Type[] types = new Type[] { typeof(int), typeof(DateTime), typeof(string), typeof(long), typeof(int?), typeof(DateTime?), typeof(long?), typeof(ApiProjectInfo) };

                // 检查参数 是否存在可初始化字段
                foreach (var property in t.GetProperties())
                {

                    if (!types.Contains(property.PropertyType))
                        continue;


                    switch (property.Name.ToLower())
                    {


                        // 用户 ID
                        case "userid":
                        case "user_id":
                        case "user_key":
                        case "userkey":
                        case "supplierkey":


                            if (property.PropertyType == typeof(int?))
                                property.SetValue(item.Value, client.Id);

                            else if (property.PropertyType == typeof(long?))
                                property.SetValue(item.Value, (long)client.Id);

                            if (property.PropertyType == typeof(int))
                                property.SetValue(item.Value, client.Id);

                            else if (property.PropertyType == typeof(long))
                                property.SetValue(item.Value, (long)client.Id);

                            else if (property.PropertyType == typeof(string))
                                property.SetValue(item.Value, client.Id.ToString());

                            break;

                        // 项目Token
                        case "projecttoken":
                        case "project_token":

                            var token = property.GetValue(item.Value);
                            if (string.IsNullOrWhiteSpace(token?.ToString()))
                            {
                                property.SetValue(item.Value, project.Token);
                            }

                            break;

                        // 写入项目信息
                        case "apiprojectinfo":
                            property.SetValue(item.Value, project);
                            break;

                        // 用户token
                        case "usertoken":
                            property.SetValue(item.Value, client.Token);
                            break;

                        case "addtime":
                        case "regtime":

                            property.SetValue(item.Value, DateTime.Now);

                            break;
                    }
                }

            }
        }

        //private ILog iLog = BuildServiceProvider.GetService<ILog>();


        public void OnActionExecuting(ActionExecutingContext context)
        {

            // 指定【Action】忽略登录验证
            var action = ((ControllerActionDescriptor)context.ActionDescriptor).ActionName;

            // 获取控制器类型
            var actionType = context.Controller.GetType().GetMethods().Where(a => a.Name == action).FirstOrDefault();

            // 获取用户Token
            var token = context.HttpContext.Request.Headers["itool-token"].ToString();


            // 检测是否是Debug项目
            var isDebug = !string.IsNullOrWhiteSpace(context.HttpContext.Request.Headers["itool-isdebug"].ToString());

            // 是否操作项目管理
            var isProjectExec = ((string)context.HttpContext.Request.Path).ToLower().StartsWith("/.v1/project");


            // Debug 项目用户种子
            int userSeed = isProjectExec ? 0 : 100000;

            // 控制器是否包含忽略登录特性
            if (actionType != null & !actionType.IsDefined(typeof(IgnoreAuthorizeAttribute), true))
            {
                if (!string.IsNullOrWhiteSpace(token))
                {
                    var result
                        = RedisQueueHelper.HashGet(RedisQueueHelperParameter.ProjectUserLogin, token);

                    if (string.IsNullOrWhiteSpace(result))
                    {
                        context.Result = new ObjectResult(new ApiResult
                        {
                            code = CodeResult.PERMISSION_NO_ACCESS,
                            info = "没有访问权限"
                        });
                        return;
                    }
                    else
                    {
                        var client = ((string)result).TryToEntity<ProjectUser>();

                        if (context.HttpContext.Items.ContainsKey("ClientInfo"))
                        {
                            context.HttpContext.Items["ClientInfo"] = new ApiClientInfo
                            {
                                Key = isDebug ? client.Id + userSeed : 1,
                                Token = isDebug ? client.Token : "system",
                                UserName = isDebug ? client.UserName : "Admin",
                                EndTime = DateTime.Now.AddDays(1)
                            };
                        }
                        else
                        {
                            context.HttpContext.Items.Add("ClientInfo", new ApiClientInfo
                            {
                                Key = isDebug ? client.Id + userSeed : 1,
                                Token = isDebug ? client.Token : "system",
                                UserName = isDebug ? client.UserName : "Admin",
                                EndTime = DateTime.Now.AddDays(1)
                            });
                        }

                        context.HttpContext.Items.Add("ProjectUser", client);

                        this.ActionArguments(context, client, (ApiProjectInfo)context.HttpContext.Items["ApiProjectInfo"]);
                    }
                }
                else
                {

                    //var projectInfo = (ApiProjectInfo)context.HttpContext.Items["ApiProjectInfo"];
                    //iLog.DeBug<ApiProjectMemberAuthorizeAttribute>($"接口禁止访问,11111", projectInfo.Token);

                    context.Result = new ObjectResult(new
                    {
                        code = CodeResult.INTERFACE_FORBIDDEN,
                        info = "接口禁止访问"
                    });
                    return;
                }
            }

        }


    }
}
